//! # 观测性中间件模块
//! 
//! 提供自动化的观测性功能，通过中间件模式简化观测性集成。
//! 支持自动上下文管理、指标记录和错误处理。

use super::traits::{ObservabilityManager, LogLevel};
use super::context::ObservabilityContext;
use rustcloud_core::{ServiceResult, ServiceError};
use std::sync::Arc;
use std::future::Future;
use std::pin::Pin;

/// 观测性中间件
/// 
/// 提供自动化的观测性功能，包装业务逻辑并自动记录相关信息。
pub struct ObservabilityMiddleware {
    /// 观测性管理器
    manager: Arc<dyn ObservabilityManager>,
    
    /// 服务名称
    service_name: String,
    
    /// 中间件配置
    config: MiddlewareConfig,
}

/// 中间件配置
#[derive(Debug, Clone)]
pub struct MiddlewareConfig {
    /// 自动记录请求指标
    pub auto_record_metrics: bool,
    
    /// 自动记录错误日志
    pub auto_log_errors: bool,
    
    /// 记录请求开始日志
    pub log_request_start: bool,
    
    /// 记录请求完成日志
    pub log_request_completion: bool,
    
    /// 慢请求阈值（毫秒）
    pub slow_request_threshold_ms: u64,
    
    /// 记录慢请求日志
    pub log_slow_requests: bool,
    
    /// 指标标签前缀
    pub metric_label_prefix: String,
}

impl Default for MiddlewareConfig {
    fn default() -> Self {
        Self {
            auto_record_metrics: true,
            auto_log_errors: true,
            log_request_start: false,
            log_request_completion: true,
            slow_request_threshold_ms: 1000, // 1秒
            log_slow_requests: true,
            metric_label_prefix: "request".to_string(),
        }
    }
}

impl ObservabilityMiddleware {
    /// 创建新的观测性中间件
    /// 
    /// # 参数
    /// * `manager` - 观测性管理器
    /// * `service_name` - 服务名称
    /// 
    /// # 返回值
    /// 新的观测性中间件实例
    pub fn new(manager: Arc<dyn ObservabilityManager>, service_name: String) -> Self {
        Self {
            manager,
            service_name,
            config: MiddlewareConfig::default(),
        }
    }

    /// 使用自定义配置创建中间件
    /// 
    /// # 参数
    /// * `manager` - 观测性管理器
    /// * `service_name` - 服务名称
    /// * `config` - 中间件配置
    /// 
    /// # 返回值
    /// 新的观测性中间件实例
    pub fn with_config(manager: Arc<dyn ObservabilityManager>, service_name: String, config: MiddlewareConfig) -> Self {
        Self {
            manager,
            service_name,
            config,
        }
    }

    /// 包装异步操作
    /// 
    /// 自动创建观测性上下文，记录操作结果，并处理错误。
    /// 
    /// # 参数
    /// * `operation_name` - 操作名称
    /// * `operation` - 要包装的异步操作
    /// 
    /// # 返回值
    /// 包装后的操作结果
    pub async fn wrap_operation<F, T>(&self, operation_name: &str, operation: F) -> ServiceResult<T>
    where
        F: Future<Output = ServiceResult<T>>,
    {
        let context_id = self.manager.start_context(self.service_name.clone(), operation_name.to_string()).await?;
        
        if self.config.log_request_start {
            self.manager.log(LogLevel::Info, &format!("开始操作: {}", operation_name), None).await?;
        }
        
        let start_time = std::time::Instant::now();
        let result = operation.await;
        let duration_ms = start_time.elapsed().as_millis() as u64;
        
        match &result {
            Ok(_) => {
                if self.config.log_request_completion {
                    self.manager.log(LogLevel::Info, &format!("操作完成: {} (耗时: {}ms)", operation_name, duration_ms), None).await?;
                }
                
                if self.config.auto_record_metrics {
                    self.record_success_metrics(operation_name, duration_ms).await?;
                }
                
                if self.config.log_slow_requests && duration_ms > self.config.slow_request_threshold_ms {
                    self.manager.log(LogLevel::Warn, &format!("慢请求检测: {} 耗时 {}ms", operation_name, duration_ms), None).await?;
                }
                
                self.manager.end_context(&context_id).await?;
            }
            Err(error) => {
                if self.config.auto_log_errors {
                    self.manager.log(LogLevel::Error, &format!("操作失败: {} - {}", operation_name, error), None).await?;
                }
                
                if self.config.auto_record_metrics {
                    self.record_error_metrics(operation_name, error).await?;
                }
                
                self.manager.record_error(&context_id, &error.to_string()).await?;
                self.manager.end_context(&context_id).await?;
            }
        }
        
        result
    }

    /// 包装带上下文的异步操作
    /// 
    /// 使用现有的观测性上下文包装操作。
    /// 
    /// # 参数
    /// * `context_id` - 现有的上下文ID
    /// * `operation_name` - 操作名称
    /// * `operation` - 要包装的异步操作
    /// 
    /// # 返回值
    /// 包装后的操作结果
    pub async fn wrap_operation_with_context<F, T>(&self, context_id: &str, operation_name: &str, operation: F) -> ServiceResult<T>
    where
        F: Future<Output = ServiceResult<T>>,
    {
        // 添加操作属性到现有上下文
        self.manager.add_context_attribute(context_id, "sub_operation".to_string(), serde_json::json!(operation_name)).await?;
        
        if self.config.log_request_start {
            self.manager.log(LogLevel::Debug, &format!("开始子操作: {}", operation_name), None).await?;
        }
        
        let start_time = std::time::Instant::now();
        let result = operation.await;
        let duration_ms = start_time.elapsed().as_millis() as u64;
        
        match &result {
            Ok(_) => {
                if self.config.log_request_completion {
                    self.manager.log(LogLevel::Debug, &format!("子操作完成: {} (耗时: {}ms)", operation_name, duration_ms), None).await?;
                }
                
                if self.config.auto_record_metrics {
                    self.record_sub_operation_metrics(operation_name, duration_ms).await?;
                }
            }
            Err(error) => {
                if self.config.auto_log_errors {
                    self.manager.log(LogLevel::Error, &format!("子操作失败: {} - {}", operation_name, error), None).await?;
                }
                
                // 记录错误到现有上下文，但不结束上下文
                self.manager.record_error(context_id, &format!("子操作错误: {}", error)).await?;
            }
        }
        
        result
    }

    /// 创建HTTP请求中间件
    /// 
    /// 专门用于HTTP请求的观测性包装。
    /// 
    /// # 参数
    /// * `method` - HTTP方法
    /// * `path` - 请求路径
    /// * `handler` - 请求处理器
    /// 
    /// # 返回值
    /// 包装后的HTTP响应
    pub async fn wrap_http_request<F, T>(&self, method: &str, path: &str, handler: F) -> ServiceResult<T>
    where
        F: Future<Output = ServiceResult<T>>,
    {
        let operation_name = format!("{} {}", method, path);
        let context_id = self.manager.start_context(self.service_name.clone(), operation_name.clone()).await?;
        
        // 添加HTTP相关属性
        self.manager.add_context_attribute(&context_id, "http.method".to_string(), serde_json::json!(method)).await?;
        self.manager.add_context_attribute(&context_id, "http.path".to_string(), serde_json::json!(path)).await?;
        
        if self.config.log_request_start {
            self.manager.log(LogLevel::Info, &format!("HTTP请求开始: {}", operation_name), None).await?;
        }
        
        let start_time = std::time::Instant::now();
        let result = handler.await;
        let duration_ms = start_time.elapsed().as_millis() as u64;
        
        match &result {
            Ok(_) => {
                if self.config.log_request_completion {
                    self.manager.log(LogLevel::Info, &format!("HTTP请求完成: {} (耗时: {}ms)", operation_name, duration_ms), None).await?;
                }
                
                if self.config.auto_record_metrics {
                    self.record_http_success_metrics(method, path, duration_ms).await?;
                }
                
                self.manager.end_context(&context_id).await?;
            }
            Err(error) => {
                if self.config.auto_log_errors {
                    self.manager.log(LogLevel::Error, &format!("HTTP请求失败: {} - {}", operation_name, error), None).await?;
                }
                
                if self.config.auto_record_metrics {
                    self.record_http_error_metrics(method, path, error).await?;
                }
                
                self.manager.record_error(&context_id, &error.to_string()).await?;
                self.manager.end_context(&context_id).await?;
            }
        }
        
        result
    }

    /// 记录成功指标
    async fn record_success_metrics(&self, operation_name: &str, duration_ms: u64) -> ServiceResult<()> {
        let mut labels = std::collections::HashMap::new();
        labels.insert("service".to_string(), self.service_name.clone());
        labels.insert("operation".to_string(), operation_name.to_string());
        labels.insert("status".to_string(), "success".to_string());
        
        // 记录请求计数
        self.manager.record_counter(&format!("{}_total", self.config.metric_label_prefix), 1.0, labels.clone()).await?;
        
        // 记录请求持续时间
        self.manager.record_histogram(&format!("{}_duration_ms", self.config.metric_label_prefix), duration_ms as f64, labels).await?;
        
        Ok(())
    }

    /// 记录错误指标
    async fn record_error_metrics(&self, operation_name: &str, error: &ServiceError) -> ServiceResult<()> {
        let mut labels = std::collections::HashMap::new();
        labels.insert("service".to_string(), self.service_name.clone());
        labels.insert("operation".to_string(), operation_name.to_string());
        labels.insert("status".to_string(), "error".to_string());
        labels.insert("error_type".to_string(), self.get_error_type(error));
        
        // 记录错误计数
        self.manager.record_counter(&format!("{}_errors_total", self.config.metric_label_prefix), 1.0, labels).await?;
        
        Ok(())
    }

    /// 记录子操作指标
    async fn record_sub_operation_metrics(&self, operation_name: &str, duration_ms: u64) -> ServiceResult<()> {
        let mut labels = std::collections::HashMap::new();
        labels.insert("service".to_string(), self.service_name.clone());
        labels.insert("sub_operation".to_string(), operation_name.to_string());
        
        // 记录子操作计数
        self.manager.record_counter("sub_operations_total", 1.0, labels.clone()).await?;
        
        // 记录子操作持续时间
        self.manager.record_histogram("sub_operations_duration_ms", duration_ms as f64, labels).await?;
        
        Ok(())
    }

    /// 记录HTTP成功指标
    async fn record_http_success_metrics(&self, method: &str, path: &str, duration_ms: u64) -> ServiceResult<()> {
        let mut labels = std::collections::HashMap::new();
        labels.insert("service".to_string(), self.service_name.clone());
        labels.insert("method".to_string(), method.to_string());
        labels.insert("path".to_string(), path.to_string());
        labels.insert("status".to_string(), "success".to_string());
        
        // 记录HTTP请求计数
        self.manager.record_counter("http_requests_total", 1.0, labels.clone()).await?;
        
        // 记录HTTP请求持续时间
        self.manager.record_histogram("http_request_duration_ms", duration_ms as f64, labels).await?;
        
        Ok(())
    }

    /// 记录HTTP错误指标
    async fn record_http_error_metrics(&self, method: &str, path: &str, error: &ServiceError) -> ServiceResult<()> {
        let mut labels = std::collections::HashMap::new();
        labels.insert("service".to_string(), self.service_name.clone());
        labels.insert("method".to_string(), method.to_string());
        labels.insert("path".to_string(), path.to_string());
        labels.insert("status".to_string(), "error".to_string());
        labels.insert("error_type".to_string(), self.get_error_type(error));
        
        // 记录HTTP错误计数
        self.manager.record_counter("http_requests_errors_total", 1.0, labels).await?;
        
        Ok(())
    }

    /// 获取错误类型字符串
    fn get_error_type(&self, error: &ServiceError) -> String {
        match error {
            ServiceError::ServiceNotFound(_) => "service_not_found".to_string(),
            ServiceError::NetworkError(_) => "network_error".to_string(),
            ServiceError::TimeoutError(_) => "timeout_error".to_string(),
            ServiceError::CircuitBreakerOpen(_) => "circuit_breaker_open".to_string(),
            ServiceError::InternalError(_) => "internal_error".to_string(),
            ServiceError::ConfigurationError(_) => "configuration_error".to_string(),
            ServiceError::SerializationError(_) => "serialization_error".to_string(),
            ServiceError::ValidationError(_) => "validation_error".to_string(),
        }
    }
}

/// 函数装饰器宏辅助结构
/// 
/// 用于简化观测性装饰器的使用。
pub struct ObservabilityDecorator {
    middleware: ObservabilityMiddleware,
}

impl ObservabilityDecorator {
    /// 创建新的装饰器
    /// 
    /// # 参数
    /// * `manager` - 观测性管理器
    /// * `service_name` - 服务名称
    /// 
    /// # 返回值
    /// 新的装饰器实例
    pub fn new(manager: Arc<dyn ObservabilityManager>, service_name: String) -> Self {
        Self {
            middleware: ObservabilityMiddleware::new(manager, service_name),
        }
    }

    /// 装饰函数
    /// 
    /// # 参数
    /// * `function_name` - 函数名称
    /// * `func` - 要装饰的函数
    /// 
    /// # 返回值
    /// 装饰后的函数结果
    pub async fn decorate<F, T>(&self, function_name: &str, func: F) -> ServiceResult<T>
    where
        F: Future<Output = ServiceResult<T>>,
    {
        self.middleware.wrap_operation(function_name, func).await
    }
}

/// 批量操作中间件
/// 
/// 专门处理批量操作的观测性记录。
pub struct BatchOperationMiddleware {
    middleware: ObservabilityMiddleware,
}

impl BatchOperationMiddleware {
    /// 创建新的批量操作中间件
    /// 
    /// # 参数
    /// * `manager` - 观测性管理器
    /// * `service_name` - 服务名称
    /// 
    /// # 返回值
    /// 新的批量操作中间件实例
    pub fn new(manager: Arc<dyn ObservabilityManager>, service_name: String) -> Self {
        Self {
            middleware: ObservabilityMiddleware::new(manager, service_name),
        }
    }

    /// 包装批量操作
    /// 
    /// # 参数
    /// * `operation_name` - 操作名称
    /// * `batch_size` - 批量大小
    /// * `operation` - 批量操作
    /// 
    /// # 返回值
    /// 批量操作结果
    pub async fn wrap_batch_operation<F, T>(&self, operation_name: &str, batch_size: usize, operation: F) -> ServiceResult<T>
    where
        F: Future<Output = ServiceResult<T>>,
    {
        let context_id = self.middleware.manager.start_context(self.middleware.service_name.clone(), operation_name.to_string()).await?;
        
        // 添加批量相关属性
        self.middleware.manager.add_context_attribute(&context_id, "batch_size".to_string(), serde_json::json!(batch_size)).await?;
        
        let start_time = std::time::Instant::now();
        let result = operation.await;
        let duration_ms = start_time.elapsed().as_millis() as u64;
        
        match &result {
            Ok(_) => {
                self.middleware.manager.log(
                    LogLevel::Info, 
                    &format!("批量操作完成: {} (批量大小: {}, 耗时: {}ms)", operation_name, batch_size, duration_ms), 
                    None
                ).await?;
                
                // 记录批量操作指标
                let mut labels = std::collections::HashMap::new();
                labels.insert("service".to_string(), self.middleware.service_name.clone());
                labels.insert("operation".to_string(), operation_name.to_string());
                labels.insert("status".to_string(), "success".to_string());
                
                self.middleware.manager.record_counter("batch_operations_total", 1.0, labels.clone()).await?;
                self.middleware.manager.record_gauge("batch_operation_size", batch_size as f64, labels.clone()).await?;
                self.middleware.manager.record_histogram("batch_operation_duration_ms", duration_ms as f64, labels).await?;
                
                self.middleware.manager.end_context(&context_id).await?;
            }
            Err(error) => {
                self.middleware.manager.log(
                    LogLevel::Error, 
                    &format!("批量操作失败: {} (批量大小: {}) - {}", operation_name, batch_size, error), 
                    None
                ).await?;
                
                self.middleware.manager.record_error(&context_id, &error.to_string()).await?;
                self.middleware.manager.end_context(&context_id).await?;
            }
        }
        
        result
    }
}